﻿using System.Collections.Generic;
using System.Linq;

namespace Collatz
{
    /// <summary>
    /// 表示截断算法的类
    /// </summary>
    public class InterceptSolver : Solver
    {
        /// <summary>
        /// 用指定的最大数值创建一个实例
        /// </summary>
        /// <param name="start">最大数值，从此数值开始向递减方向解算</param>
        /// <exception cref="ArgumentOutOfRangeException">当<paramref name="start"/>不是正整数时引发</exception>
        public InterceptSolver(int start)
            : base(start)
        {
            _dictionary = new Dictionary<long, long>() { { 1, 1 } };
        }

        private readonly Dictionary<long, long> _dictionary;

        /// <summary>
        /// 从<see cref="Start"/>开始依次递减，解算最长序列
        /// </summary>
        /// <returns>最长序列的开始数值</returns>
        public override int Solve()
        {
            return Enumerable
                .Range(1, _start)
                .Reverse()
                .Aggregate((number1, number2) => Count(number1) > Count(number2) ? number1 : number2);
        }

        /// <summary>
        /// 获取以指定数值为开头的序列长度
        /// </summary>
        /// <param name="start">以此数值作为序列开头</param>
        /// <returns>序列长度</returns>
        private long Count(long start)
        {
            if (_dictionary.ContainsKey(start))
            {
                return _dictionary[start];
            }
            else
            {
                var enumerator = new CollatzSerial(start).GetEnumerator();
                enumerator.MoveNext();
                enumerator.MoveNext();
                var length = 1 + Count(enumerator.Current);
                _dictionary.Add(start, length);
                return length;
            }
        }
    }
}
